package com.ayf.payment.game.api.wx;

import com.alibaba.fastjson.JSON;
import com.ayf.payment.game.api.dto.MerchantCommonDTO;
import com.ayf.payment.game.api.dto.platform.WxGatewayAddressDTO;
import com.ayf.payment.game.api.entity.Merchant;
import com.ayf.payment.game.api.entity.platform.WxConfig;
import com.ayf.payment.game.api.entity.platform.WxGatewayAddress;
import com.ayf.payment.game.api.service.MerchantService;
import com.ayf.payment.game.api.service.platform.WxConfigService;
import com.ayf.payment.game.api.service.platform.WxGatewayAddressService;
import com.ayf.payment.game.api.utils.*;
import com.swwx.charm.commons.lang.utils.LogPortal;
import org.apache.commons.lang.StringUtils;
import org.jdom2.Element;
import org.jdom2.input.SAXBuilder;
import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.List;

/**
 * @author wwl
 * @description:
 * @date 2020/7/31 15:04
 */
@RestController
@RequestMapping("/wx/gateway")
public class WxGatewayController {

    @Autowired
    private WxGatewayAddressService wxGatewayAddressService;

    @Autowired
    private MerchantService merchantService;

    @Resource
    private WxGatewayConfig wxGatewayConfig;

    @Autowired
    private WxConfigService wxConfigService;

    /**
     * 用于验证消息的确来自微信服务器
     *
     * @param checkWeChat 微信验证实体类
     * @return String 原样返回随机字符串
     */
    @GetMapping("index")
    public String index(CheckWeChat checkWeChat, HttpServletRequest request) {
        LogPortal.info("DTMB 验证消息的确来自微信服务器-request参数[{}]", JSON.toJSONString(request.getParameterMap()));
        checkWeChat.setTimestamp(request.getParameter("timestamp"));
        checkWeChat.setEchostr(request.getParameter("echostr"));
        checkWeChat.setNonce(request.getParameter("nonce"));
        checkWeChat.setSignature(request.getParameter("signature"));
        LogPortal.info("DTMB 验证消息的确来自微信服务器-checkWeChat参数[{}]", JSON.toJSONString(checkWeChat));
        //校验微信加密签名signature
         return checkWeChat.getEchostr();
    }

    /**
     * 消息管理
     *
     * @param request 请求
     * @return String 类型的xml字符串
     */
    @PostMapping("index")
    public String msgIndex(HttpServletRequest request) {
        String traceId = SnowFlakeUtils.getUniqueId();
        String xml =  messageHandle(request,traceId);

        return xml;
    }

    public String messageHandle(HttpServletRequest request, String traceId) {
        try {
            //获取根元素
            Element root = new SAXBuilder().build(request.getInputStream()).getRootElement();

            String toUserName = root.getChildText("ToUserName");
            //发送方帐号（一个OpenID）
            String fromUserName = root.getChildText("FromUserName");
            //消息创建时间 （整型）
            String createTime = root.getChildText("CreateTime");
            //消息类型
            String msgType = root.getChildText("MsgType");
            //事件
            String event = root.getChildText("Event");
            //内容
            String content = root.getChildText("Content");
            LogPortal.info("{} 微信消息管理参数[toUserName:{},fromUserName:{},createTime:{},msgType:{},event:{},content:{}]",traceId,
                    toUserName, fromUserName, createTime, msgType, event, content);

            if ("event".equals(msgType)) {
                WxConfig wxConfig=wxConfigService.getGameConfig(toUserName);
                //进入事件类型消息
                String eventKey = root.getChildText("EventKey");
                LogPortal.info("{} [{}]进入事件类型消息,场景值[{}]",traceId, fromUserName, eventKey);

                if ("subscribe".equals(event)) {
                    return formatTextXml(fromUserName,toUserName,wxConfig.getAttentionReply());
                }else if ("unsubscribe".equals(event)) {
                    return formatTextXml(fromUserName,toUserName,wxConfig.getAttentionReply());
                } else if ("CLICK".equals(event)) {
                    LogPortal.info("[{}]进入点击菜单事件", fromUserName);
                    if ("KE_FU".equals(eventKey)) {
                        LogPortal.info("[{}]进入获取客服信息事件", fromUserName);
                        WxConfig gameConfig = wxConfigService.getGameConfig(toUserName);
                        if (gameConfig == null || gameConfig.getMerchantId() == null) {
                            return "";
                        }
                        MerchantCommonDTO merchantDTO = merchantService.getMerchantCommon(gameConfig.getMerchantId());
                        if (merchantDTO == null) {
                            return "";
                        }
                        String qq = "";
                        if (StringUtils.isNotBlank(merchantDTO.getCustomerQq())) {
                            qq = merchantDTO.getCustomerQq();
                        } else if (StringUtils.isNotBlank(merchantDTO.getQq())) {
                            qq = merchantDTO.getQq();
                        }
                        if (StringUtils.isEmpty(qq)) {
                            return formatTextXml(fromUserName, toUserName, "暂无客服");
                        } else {
                            return formatTextXml(fromUserName, toUserName, qq);
                        }
                    }
                }
            }
            String nickname=getWxNicknameByOpenid(fromUserName,toUserName,traceId);
            //执行消息处理
            StringBuffer buffer=new StringBuffer();
            buffer.append(toUserName).append("|").append(fromUserName).append("|");
            buffer.append(msgType).append("|").append(event).append("|").append(content).append("|").append(nickname);
            List<WxGatewayAddressDTO> list= wxGatewayAddressService.selectByWxOriginId(toUserName,null);
            if(null !=list && !list.isEmpty()){
                int code=0;
                String msg="";
                for(WxGatewayAddressDTO wxGatewayAddress:list){

                    String url=WxGatewayConfig.WX_GATEWAY_PATH + wxGatewayAddress.getUserIp() + WxGatewayConfig.WX_GATEWAY_URL;
                    try {
                        CommonResult commonResult = WxHttpUtil.doPostGetWay(url, buffer.toString(),traceId);
                        code = commonResult.getCode();
                        msg = commonResult.getMsg();
                        LogPortal.info("{} Wx 公众号消息广播请求URL:[{}] 返回信息：code:[{}] msg:[{}]", traceId,WxGatewayConfig.WX_GATEWAY_PATH + wxGatewayAddress.getUserIp() + WxGatewayConfig.WX_GATEWAY_URL, commonResult.getCode(),commonResult.getMsg());

                        if (code == 0 && !"请输入正确验证码".equals(msg)) {
                            return formatTextXml(fromUserName, toUserName, commonResult.getMsg());
                        }
                    }catch (Exception e){
                        LogPortal.error("{} Wx 公众号消息广播请求错误URL:[{}] 内容：[{}]", e,traceId,WxGatewayConfig.WX_GATEWAY_PATH + wxGatewayAddress.getUserIp() + WxGatewayConfig.WX_GATEWAY_URL, buffer.toString());
                    }
                }
                if(code==0 && "请输入正确验证码".equals(msg)){
                    return formatTextXml(fromUserName,toUserName,msg);
                }
            }
            return formatTextXml(fromUserName,toUserName,"验证失败");
        } catch (Exception e) {
            LogPortal.error("{} 微信回复数据异常错误",e,traceId);
        }

        return "验证失败";
    }

    public String getWxNicknameByOpenid(String openid ,String toUserName,String traceId){
        WxConfig wxConfig=wxConfigService.getGameConfig(toUserName);

        String nickname="";
        try {
            String wxUrl = "https://api.weixin.qq.com/cgi-bin/user/info?access_token=" +wxGatewayConfig.getAccessToken(wxConfig).getAccessToken() + "&openid=" + openid + "&lang=zh_CN";
            JSONObject jsonObject = WxHttpUtil.doGet("获取用户详情信息".concat(openid),wxUrl);
            LogPortal.info("{} 获取用户详情信息  请求[{}] 返回信息：{}",traceId,wxUrl,jsonObject.toString());
            nickname = (String) jsonObject.get("nickname");
            return WxGatewayConfig.filterEmoji(nickname);
        }catch (Exception e){
            LogPortal.error("{} 获取用户详情信息 异常！",e);
        }
        return nickname;
    }

    public String formatTextXml(String fromUserName, String toUserName, String content) {
        return "<xml>\n" +
                "  <ToUserName><![CDATA[" + fromUserName + "]]></ToUserName>\n" +
                "  <FromUserName><![CDATA[" + toUserName + "]]></FromUserName>\n" +
                "  <CreateTime>" + System.currentTimeMillis() + "</CreateTime>\n" +
                "  <MsgType><![CDATA[text]]></MsgType>\n" +
                "  <Content><![CDATA[" + content + "]]></Content>\n" +
                "</xml>";
    }



    @PostMapping("sendMsg")
    public String sendMsg(HttpServletRequest request) throws Exception {
        String singStr = request.getHeader("EncryptedInformation");
        String dataStr = AESUtil.aes128Decrypt(singStr, WxGatewayConfig.SECRET_KEY);
        LogPortal.info("WX GateWay WXTuisong 接收到的信息{}",dataStr);
        WxSendMsg wxSendMsg=JsonUtils.fromJson(dataStr,WxSendMsg.class);
        sendCustomMessage(wxSendMsg);
        return "ok";
    }

    public void sendCustomMessage(WxSendMsg wxSendMsg) {
        WxConfig wxConfig=wxConfigService.getGameConfig(wxSendMsg.getWxOriginId());
        String postUrl = "https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token=" + wxGatewayConfig.getAccessToken(wxConfig).getAccessToken();
        //推送图文消息
        Message message = new Message();
        message.setTouser(wxSendMsg.getOpenid());//普通用户openid
        message.setMsgtype("text");//图文消息（点击跳转到外链）为news
        TextContent text=new TextContent();
        text.setContent(wxSendMsg.getMsg());
        message.setText(text);
        String jsonStr= JsonUtils.toJson(message);
        LogPortal.info("WX GateWay WXTuisong 发送的信息{}",jsonStr);
        String msgStr= WxHttpUtil.postJsonData(postUrl, jsonStr);
        LogPortal.info("WX GateWay WXTuisong {}给用户{}推送消息{}返回信息{}",postUrl,wxSendMsg.getOpenid(),jsonStr,msgStr);
    }

    @PostMapping("login")
    public String wxGatewayLogin(HttpServletRequest request){
        String ip = IPUtils.getIp(request);
        LogPortal.info("WX GateWay  微信网关连接 用户ip:[{}]",ip);
        try {
            String singStr = request.getHeader("EncryptedInformation");
            String sgin = AESUtil.aes128Decrypt(singStr, WxGatewayConfig.SECRET_KEY);
            String[] msgArray = sgin.split("\\|");
            String merchantId = msgArray[0];
            String wxOriginId = msgArray[1];
            LogPortal.info("WX GateWay  微信网关连接 用户ID:[{}]",merchantId);
            Merchant merchant = merchantService.find(Integer.parseInt(merchantId));
            if (null == merchant) {
                return "false";
            }
            WxGatewayAddress wxGatewayAddress = new WxGatewayAddress();
            wxGatewayAddress.setMerchantId(Integer.parseInt(merchantId));
            wxGatewayAddress.setStatus(1);
            wxGatewayAddress.setUserIp(ip);
            wxGatewayAddress.setWxOriginId(wxOriginId);
            wxGatewayAddress.setCreateTime(new Date());
            boolean bool= wxGatewayAddressService.inster(wxGatewayAddress);
            if(bool) {
                return "ok";
            }else{
                return "false";
            }
        }catch (Exception e){
            LogPortal.info("WX GateWay connection failed 微信网关连接失败",e);
            return "false";
        }
    }

//    @PostMapping("getAccessToken")
//    public String getAccessToken(HttpServletRequest request){
//        try {
//            String singStr = request.getHeader("EncryptedInformation");
//            String sgin = AESUtil.aes128Decrypt(singStr, WxGatewayConfig.SECRET_KEY);
//
//            WxConfig wxConfig=wxConfigService.getGameConfig(sgin);
//            WxGatewayAccessToken  accessToken=WxGatewayConfig.getAccessToken(wxConfig);
//
//            String accessTokenJson=AESUtil.aes128Encrypt(accessToken.getAccessToken(),WxGatewayConfig.SECRET_KEY);
//            return accessTokenJson;
//        }catch (Exception e){
//            LogPortal.info("WX GateWay 获取AccessToken 失败",e);
//        }
//        return "";
//    }

}
